﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using StructureMap;
using System.Collections;

namespace Beginner.Infrastructure.Engines
{
    public class EngineContainer : IEngine
    {
        public EngineContainer(IContainer container)
        {
            if (container == null)
                throw new ArgumentNullException("container");
            _container = container;
        }

        private readonly IContainer _container;

        public object GetInstance(Type type)
        {
            if (type == null)
            {
                return null;
            }

            try
            {
                return type.IsAbstract || type.IsInterface
                       ? _container.TryGetInstance(type)
                       : _container.GetInstance(type);
            }
            catch (StructureMapException ex)
            {
                var message = ex.Message + "\n" + _container.WhatDoIHave();
                throw new Exception(message);
            }
        }

        public object TryGetInstance(Type type)
        {
            if (type == null)
            {
                return null;
            }

            try
            {
                return type.IsAbstract || type.IsInterface
                       ? _container.TryGetInstance(type)
                       : _container.GetInstance(type);
            }
            catch (StructureMapException ex)
            {
                var message = ex.Message + "\n" + _container.WhatDoIHave();
                throw new Exception(message);
            }
        }

        public IEnumerable<T> GetAllInstances<T>(Type type)
        {
            try
            {
                return _container.GetAllInstances(type).OfType<T>() as IEnumerable<T>;
            }
            catch (StructureMapException ex)
            {
                var message = ex.Message + "\n" + _container.WhatDoIHave();
                throw new Exception(message);
            }
        }

        public void Release(object instance)
        {
            _container.Release(instance);
        }
    }
}
